1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gtk.ListStore;
26 
27 private import glib.ConstructionException;
28 private import glib.MemorySlice;
29 private import gobject.ObjectG;
30 private import gobject.Value;
31 private import gtk.BuildableIF;
32 private import gtk.BuildableT;
33 private import gtk.TreeDragDestIF;
34 private import gtk.TreeDragDestT;
35 private import gtk.TreeDragSourceIF;
36 private import gtk.TreeDragSourceT;
37 private import gtk.TreeIter;
38 private import gtk.TreeModelIF;
39 private import gtk.TreeModelT;
40 private import gtk.TreeSortableIF;
41 private import gtk.TreeSortableT;
42 private import gtk.c.functions;
43 public  import gtk.c.types;
44 
45 
46 /**
47  * A list-like data structure that can be used with the [class@Gtk.TreeView].
48  * 
49  * The `GtkListStore` object is a list model for use with a `GtkTreeView`
50  * widget.  It implements the `GtkTreeModel` interface, and consequentialy,
51  * can use all of the methods available there.  It also implements the
52  * `GtkTreeSortable` interface so it can be sorted by the view.
53  * Finally, it also implements the tree
54  * [drag](iface.TreeDragSource.html) and [drop](iface.TreeDragDest.html)
55  * interfaces.
56  * 
57  * The `GtkListStore` can accept most `GType`s as a column type, though
58  * it can’t accept all custom types.  Internally, it will keep a copy of
59  * data passed in (such as a string or a boxed pointer).  Columns that
60  * accept `GObject`s are handled a little differently.  The
61  * `GtkListStore` will keep a reference to the object instead of copying the
62  * value.  As a result, if the object is modified, it is up to the
63  * application writer to call [method@Gtk.TreeModel.row_changed] to emit the
64  * [signal@Gtk.TreeModel::row_changed] signal. This most commonly affects lists
65  * with [class@Gdk.Texture]s stored.
66  * 
67  * An example for creating a simple list store:
68  * 
69  * ```c
70  * enum {
71  * COLUMN_STRING,
72  * COLUMN_INT,
73  * COLUMN_BOOLEAN,
74  * N_COLUMNS
75  * };
76  * 
77  * {
78  * GtkListStore *list_store;
79  * GtkTreePath *path;
80  * GtkTreeIter iter;
81  * int i;
82  * 
83  * list_store = gtk_list_store_new (N_COLUMNS,
84  * G_TYPE_STRING,
85  * G_TYPE_INT,
86  * G_TYPE_BOOLEAN);
87  * 
88  * for (i = 0; i < 10; i++)
89  * {
90  * char *some_data;
91  * 
92  * some_data = get_some_data (i);
93  * 
94  * // Add a new row to the model
95  * gtk_list_store_append (list_store, &iter);
96  * gtk_list_store_set (list_store, &iter,
97  * COLUMN_STRING, some_data,
98  * COLUMN_INT, i,
99  * COLUMN_BOOLEAN,  FALSE,
100  * -1);
101  * 
102  * // As the store will keep a copy of the string internally,
103  * // we free some_data.
104  * g_free (some_data);
105  * }
106  * 
107  * // Modify a particular row
108  * path = gtk_tree_path_new_from_string ("4");
109  * gtk_tree_model_get_iter (GTK_TREE_MODEL (list_store),
110  * &iter,
111  * path);
112  * gtk_tree_path_free (path);
113  * gtk_list_store_set (list_store, &iter,
114  * COLUMN_BOOLEAN, TRUE,
115  * -1);
116  * }
117  * ```
118  * 
119  * # Performance Considerations
120  * 
121  * Internally, the `GtkListStore` was originally implemented with a linked list
122  * with a tail pointer.  As a result, it was fast at data insertion and deletion,
123  * and not fast at random data access.  The `GtkListStore` sets the
124  * `GTK_TREE_MODEL_ITERS_PERSIST` flag, which means that `GtkTreeIter`s can be
125  * cached while the row exists.  Thus, if access to a particular row is needed
126  * often and your code is expected to run on older versions of GTK, it is worth
127  * keeping the iter around.
128  * 
129  * # Atomic Operations
130  * 
131  * It is important to note that only the methods
132  * gtk_list_store_insert_with_values() and gtk_list_store_insert_with_valuesv()
133  * are atomic, in the sense that the row is being appended to the store and the
134  * values filled in in a single operation with regard to `GtkTreeModel` signaling.
135  * In contrast, using e.g. gtk_list_store_append() and then gtk_list_store_set()
136  * will first create a row, which triggers the `GtkTreeModel::row-inserted` signal
137  * on `GtkListStore`. The row, however, is still empty, and any signal handler
138  * connecting to `GtkTreeModel::row-inserted` on this particular store should be prepared
139  * for the situation that the row might be empty. This is especially important
140  * if you are wrapping the `GtkListStore` inside a `GtkTreeModel`Filter and are
141  * using a `GtkTreeModel`FilterVisibleFunc. Using any of the non-atomic operations
142  * to append rows to the `GtkListStore` will cause the
143  * `GtkTreeModel`FilterVisibleFunc to be visited with an empty row first; the
144  * function must be prepared for that.
145  * 
146  * # GtkListStore as GtkBuildable
147  * 
148  * The GtkListStore implementation of the [iface@Gtk.Buildable] interface allows
149  * to specify the model columns with a `<columns>` element that may contain
150  * multiple `<column>` elements, each specifying one model column. The “type”
151  * attribute specifies the data type for the column.
152  * 
153  * Additionally, it is possible to specify content for the list store
154  * in the UI definition, with the `<data>` element. It can contain multiple
155  * `<row>` elements, each specifying to content for one row of the list model.
156  * Inside a `<row>`, the `<col>` elements specify the content for individual cells.
157  * 
158  * Note that it is probably more common to define your models in the code,
159  * and one might consider it a layering violation to specify the content of
160  * a list store in a UI definition, data, not presentation, and common wisdom
161  * is to separate the two, as far as possible.
162  * 
163  * An example of a UI Definition fragment for a list store:
164  * 
165  * ```xml
166  * <object class="GtkListStore">
167  * <columns>
168  * <column type="gchararray"/>
169  * <column type="gchararray"/>
170  * <column type="gint"/>
171  * </columns>
172  * <data>
173  * <row>
174  * <col id="0">John</col>
175  * <col id="1">Doe</col>
176  * <col id="2">25</col>
177  * </row>
178  * <row>
179  * <col id="0">Johan</col>
180  * <col id="1">Dahlin</col>
181  * <col id="2">50</col>
182  * </row>
183  * </data>
184  * </object>
185  * ```
186  */
187 public class ListStore : ObjectG, BuildableIF, TreeDragDestIF, TreeDragSourceIF, TreeModelIF, TreeSortableIF
188 {
189 	/** the main Gtk struct */
190 	protected GtkListStore* gtkListStore;
191 
192 	/** Get the main Gtk struct */
193 	public GtkListStore* getListStoreStruct(bool transferOwnership = false)
194 	{
195 		if (transferOwnership)
196 			ownedRef = false;
197 		return gtkListStore;
198 	}
199 
200 	/** the main Gtk struct as a void* */
201 	protected override void* getStruct()
202 	{
203 		return cast(void*)gtkListStore;
204 	}
205 
206 	/**
207 	 * Sets our main struct and passes it to the parent class.
208 	 */
209 	public this (GtkListStore* gtkListStore, bool ownedRef = false)
210 	{
211 		this.gtkListStore = gtkListStore;
212 		super(cast(GObject*)gtkListStore, ownedRef);
213 	}
214 
215 	// add the Buildable capabilities
216 	mixin BuildableT!(GtkListStore);
217 
218 	// add the TreeDragDest capabilities
219 	mixin TreeDragDestT!(GtkListStore);
220 
221 	// add the TreeDragSource capabilities
222 	mixin TreeDragSourceT!(GtkListStore);
223 
224 	// add the TreeModel capabilities
225 	mixin TreeModelT!(GtkListStore);
226 
227 	// add the TreeSortable capabilities
228 	mixin TreeSortableT!(GtkListStore);
229 
230 	/**
231 	 * Creates a top level iteractor.
232 	 * I don't think lists have but the top level iteractor
233 	 */
234 	TreeIter createIter()
235 	{
236 		GtkTreeIter* iter = new GtkTreeIter;
237 		gtk_list_store_append(getListStoreStruct(), iter);
238 		return new TreeIter(iter);
239 	}
240 
241 	/** */
242 	void setValue(TYPE)(TreeIter iter, int column, TYPE value)
243 	{
244 		Value v = new Value(value);
245 		gtk_list_store_set_value(gtkListStore, iter.getTreeIterStruct(), column, v.getValueStruct());
246 	}
247 
248 	/**
249 	 */
250 
251 	/** */
252 	public static GType getType()
253 	{
254 		return gtk_list_store_get_type();
255 	}
256 
257 	/**
258 	 * Non-vararg creation function.  Used primarily by language bindings.
259 	 *
260 	 * Params:
261 	 *     types = an array of `GType` types for the columns, from first to last
262 	 *
263 	 * Returns: a new `GtkListStore`
264 	 *
265 	 * Throws: ConstructionException GTK+ fails to create the object.
266 	 */
267 	public this(GType[] types)
268 	{
269 		auto __p = gtk_list_store_newv(cast(int)types.length, types.ptr);
270 
271 		if(__p is null)
272 		{
273 			throw new ConstructionException("null returned by newv");
274 		}
275 
276 		this(cast(GtkListStore*) __p, true);
277 	}
278 
279 	/**
280 	 * Appends a new row to @list_store.  @iter will be changed to point to this new
281 	 * row.  The row will be empty after this function is called.  To fill in
282 	 * values, you need to call gtk_list_store_set() or gtk_list_store_set_value().
283 	 *
284 	 * Params:
285 	 *     iter = An unset `GtkTreeIter` to set to the appended row
286 	 */
287 	public void append(out TreeIter iter)
288 	{
289 		GtkTreeIter* outiter = sliceNew!GtkTreeIter();
290 
291 		gtk_list_store_append(gtkListStore, outiter);
292 
293 		iter = ObjectG.getDObject!(TreeIter)(outiter, true);
294 	}
295 
296 	/**
297 	 * Removes all rows from the list store.
298 	 */
299 	public void clear()
300 	{
301 		gtk_list_store_clear(gtkListStore);
302 	}
303 
304 	/**
305 	 * Creates a new row at @position.  @iter will be changed to point to this new
306 	 * row.  If @position is -1 or is larger than the number of rows on the list,
307 	 * then the new row will be appended to the list. The row will be empty after
308 	 * this function is called.  To fill in values, you need to call
309 	 * gtk_list_store_set() or gtk_list_store_set_value().
310 	 *
311 	 * Params:
312 	 *     iter = An unset `GtkTreeIter` to set to the new row
313 	 *     position = position to insert the new row, or -1 for last
314 	 */
315 	public void insert(out TreeIter iter, int position)
316 	{
317 		GtkTreeIter* outiter = sliceNew!GtkTreeIter();
318 
319 		gtk_list_store_insert(gtkListStore, outiter, position);
320 
321 		iter = ObjectG.getDObject!(TreeIter)(outiter, true);
322 	}
323 
324 	/**
325 	 * Inserts a new row after @sibling. If @sibling is %NULL, then the row will be
326 	 * prepended to the beginning of the list. @iter will be changed to point to
327 	 * this new row. The row will be empty after this function is called. To fill
328 	 * in values, you need to call gtk_list_store_set() or gtk_list_store_set_value().
329 	 *
330 	 * Params:
331 	 *     iter = An unset `GtkTreeIter` to set to the new row
332 	 *     sibling = A valid `GtkTreeIter`
333 	 */
334 	public void insertAfter(out TreeIter iter, TreeIter sibling)
335 	{
336 		GtkTreeIter* outiter = sliceNew!GtkTreeIter();
337 
338 		gtk_list_store_insert_after(gtkListStore, outiter, (sibling is null) ? null : sibling.getTreeIterStruct());
339 
340 		iter = ObjectG.getDObject!(TreeIter)(outiter, true);
341 	}
342 
343 	/**
344 	 * Inserts a new row before @sibling. If @sibling is %NULL, then the row will
345 	 * be appended to the end of the list. @iter will be changed to point to this
346 	 * new row. The row will be empty after this function is called. To fill in
347 	 * values, you need to call gtk_list_store_set() or gtk_list_store_set_value().
348 	 *
349 	 * Params:
350 	 *     iter = An unset `GtkTreeIter` to set to the new row
351 	 *     sibling = A valid `GtkTreeIter`
352 	 */
353 	public void insertBefore(out TreeIter iter, TreeIter sibling)
354 	{
355 		GtkTreeIter* outiter = sliceNew!GtkTreeIter();
356 
357 		gtk_list_store_insert_before(gtkListStore, outiter, (sibling is null) ? null : sibling.getTreeIterStruct());
358 
359 		iter = ObjectG.getDObject!(TreeIter)(outiter, true);
360 	}
361 
362 	/**
363 	 * A variant of gtk_list_store_insert_with_values() which
364 	 * takes the columns and values as two arrays, instead of
365 	 * varargs.
366 	 *
367 	 * This function is mainly intended for language-bindings.
368 	 *
369 	 * Params:
370 	 *     iter = An unset `GtkTreeIter` to set to the new row
371 	 *     position = position to insert the new row, or -1 for last
372 	 *     columns = an array of column numbers
373 	 *     values = an array of GValues
374 	 */
375 	public void insertWithValuesv(out TreeIter iter, int position, int[] columns, Value[] values)
376 	{
377 		GtkTreeIter* outiter = sliceNew!GtkTreeIter();
378 
379 		GValue[] valuesArray = new GValue[values.length];
380 		for ( int i = 0; i < values.length; i++ )
381 		{
382 			valuesArray[i] = *(values[i].getValueStruct());
383 		}
384 
385 		gtk_list_store_insert_with_valuesv(gtkListStore, outiter, position, columns.ptr, valuesArray.ptr, cast(int)values.length);
386 
387 		iter = ObjectG.getDObject!(TreeIter)(outiter, true);
388 	}
389 
390 	/**
391 	 * Checks if the given iter is a valid iter for this `GtkListStore`.
392 	 *
393 	 * This function is slow. Only use it for debugging and/or testing
394 	 * purposes.
395 	 *
396 	 * Params:
397 	 *     iter = the iterator to check
398 	 *
399 	 * Returns: %TRUE if the iter is valid, %FALSE if the iter is invalid.
400 	 */
401 	public bool iterIsValid(TreeIter iter)
402 	{
403 		return gtk_list_store_iter_is_valid(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct()) != 0;
404 	}
405 
406 	/**
407 	 * Moves @iter in @store to the position after @position. Note that this
408 	 * function only works with unsorted stores. If @position is %NULL, @iter
409 	 * will be moved to the start of the list.
410 	 *
411 	 * Params:
412 	 *     iter = A `GtkTreeIter`
413 	 *     position = A `GtkTreeIter`
414 	 */
415 	public void moveAfter(TreeIter iter, TreeIter position)
416 	{
417 		gtk_list_store_move_after(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), (position is null) ? null : position.getTreeIterStruct());
418 	}
419 
420 	/**
421 	 * Moves @iter in @store to the position before @position. Note that this
422 	 * function only works with unsorted stores. If @position is %NULL, @iter
423 	 * will be moved to the end of the list.
424 	 *
425 	 * Params:
426 	 *     iter = A `GtkTreeIter`
427 	 *     position = A `GtkTreeIter`
428 	 */
429 	public void moveBefore(TreeIter iter, TreeIter position)
430 	{
431 		gtk_list_store_move_before(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), (position is null) ? null : position.getTreeIterStruct());
432 	}
433 
434 	/**
435 	 * Prepends a new row to @list_store. @iter will be changed to point to this new
436 	 * row. The row will be empty after this function is called. To fill in
437 	 * values, you need to call gtk_list_store_set() or gtk_list_store_set_value().
438 	 *
439 	 * Params:
440 	 *     iter = An unset `GtkTreeIter` to set to the prepend row
441 	 */
442 	public void prepend(out TreeIter iter)
443 	{
444 		GtkTreeIter* outiter = sliceNew!GtkTreeIter();
445 
446 		gtk_list_store_prepend(gtkListStore, outiter);
447 
448 		iter = ObjectG.getDObject!(TreeIter)(outiter, true);
449 	}
450 
451 	/**
452 	 * Removes the given row from the list store.  After being removed,
453 	 * @iter is set to be the next valid row, or invalidated if it pointed
454 	 * to the last row in @list_store.
455 	 *
456 	 * Params:
457 	 *     iter = A valid `GtkTreeIter`
458 	 *
459 	 * Returns: %TRUE if @iter is valid, %FALSE if not.
460 	 */
461 	public bool remove(TreeIter iter)
462 	{
463 		return gtk_list_store_remove(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct()) != 0;
464 	}
465 
466 	/**
467 	 * Reorders @store to follow the order indicated by @new_order. Note that
468 	 * this function only works with unsorted stores.
469 	 *
470 	 * Params:
471 	 *     newOrder = an array of integers mapping the new
472 	 *         position of each child to its old position before the re-ordering,
473 	 *         i.e. @new_order`[newpos] = oldpos`. It must have
474 	 *         exactly as many items as the list store’s length.
475 	 */
476 	public void reorder(int[] newOrder)
477 	{
478 		gtk_list_store_reorder(gtkListStore, newOrder.ptr);
479 	}
480 
481 	/**
482 	 * This function is meant primarily for `GObject`s that inherit from `GtkListStore`,
483 	 * and should only be used when constructing a new `GtkListStore`.  It will not
484 	 * function after a row has been added, or a method on the `GtkTreeModel`
485 	 * interface is called.
486 	 *
487 	 * Params:
488 	 *     types = An array length n of `GType`s
489 	 */
490 	public void setColumnTypes(GType[] types)
491 	{
492 		gtk_list_store_set_column_types(gtkListStore, cast(int)types.length, types.ptr);
493 	}
494 
495 	/**
496 	 * See gtk_list_store_set(); this version takes a va_list for use by language
497 	 * bindings.
498 	 *
499 	 * Params:
500 	 *     iter = A valid `GtkTreeIter` for the row being modified
501 	 *     varArgs = va_list of column/value pairs
502 	 */
503 	public void setValist(TreeIter iter, void* varArgs)
504 	{
505 		gtk_list_store_set_valist(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), varArgs);
506 	}
507 
508 	/**
509 	 * Sets the data in the cell specified by @iter and @column.
510 	 * The type of @value must be convertible to the type of the
511 	 * column.
512 	 *
513 	 * Params:
514 	 *     iter = A valid `GtkTreeIter` for the row being modified
515 	 *     column = column number to modify
516 	 *     value = new value for the cell
517 	 */
518 	public void setValue(TreeIter iter, int column, Value value)
519 	{
520 		gtk_list_store_set_value(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), column, (value is null) ? null : value.getValueStruct());
521 	}
522 
523 	/**
524 	 * A variant of gtk_list_store_set_valist() which
525 	 * takes the columns and values as two arrays, instead of
526 	 * varargs. This function is mainly intended for
527 	 * language-bindings and in case the number of columns to
528 	 * change is not known until run-time.
529 	 *
530 	 * Params:
531 	 *     iter = A valid `GtkTreeIter` for the row being modified
532 	 *     columns = an array of column numbers
533 	 *     values = an array of GValues
534 	 */
535 	public void setValuesv(TreeIter iter, int[] columns, Value[] values)
536 	{
537 		GValue[] valuesArray = new GValue[values.length];
538 		for ( int i = 0; i < values.length; i++ )
539 		{
540 			valuesArray[i] = *(values[i].getValueStruct());
541 		}
542 
543 		gtk_list_store_set_valuesv(gtkListStore, (iter is null) ? null : iter.getTreeIterStruct(), columns.ptr, valuesArray.ptr, cast(int)values.length);
544 	}
545 
546 	/**
547 	 * Swaps @a and @b in @store. Note that this function only works with
548 	 * unsorted stores.
549 	 *
550 	 * Params:
551 	 *     a = A `GtkTreeIter`
552 	 *     b = Another `GtkTreeIter`
553 	 */
554 	public void swap(TreeIter a, TreeIter b)
555 	{
556 		gtk_list_store_swap(gtkListStore, (a is null) ? null : a.getTreeIterStruct(), (b is null) ? null : b.getTreeIterStruct());
557 	}
558 }